﻿using System;
using System.Collections.Generic;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;

namespace BLLayer
{
    public class Label3DManager
    {
        private const double Depth = 20;
        private const double Height = 100;
        private const string BaseText = "A00";
        private static readonly Label3DManager Manager = new Label3DManager();

        private readonly Dictionary<string, List<IText3DElement>> _label3DSource =
            new Dictionary<string, List<IText3DElement>>();

        private Label3DManager()
        {
        }

        public List<IText3DElement> this[string layerName]
        {
            get
            {
                if (string.IsNullOrEmpty(layerName))
                    throw new ArgumentNullException(layerName);
                return !_label3DSource.ContainsKey(layerName) ? null : _label3DSource[layerName];
            }
        }

        public static Label3DManager GetManager()
        {
            return Manager;
        }

        public List<IText3DElement> Update(string layerName)
        {
            if (!_label3DSource.ContainsKey(layerName))
                throw new Exception("更新标注失败");
            _label3DSource[layerName].Clear();
            var elements = Create();
            _label3DSource[layerName].AddRange(elements);
            return elements;
        }

        public List<IText3DElement> Add(string layerName)
        {
            if (_label3DSource.ContainsKey(layerName))
                throw new Exception("增加标注失败");
            var elements = Create();
            _label3DSource.Add(layerName, elements);
            return elements;
        }

        private List<IText3DElement> Create()
        {
            var dataSource = new OpenGeodataSource();
            var featureClass = dataSource.OpenShapeAndDataSets();
            if (featureClass.ShapeType != esriGeometryType.esriGeometryPoint)
                throw new Exception("请选择点要素作为生成标注的数据源！");
            var featureCursor = featureClass.Search(null, false);
            var feature = featureCursor.NextFeature();
            var index = 1;
            var elements = new List<IText3DElement>();
            while (feature != null)
            {
                var point = feature.Shape as IPoint;
                if (point == null) break;
                IText3DElement element = new Text3DElementClass
                {
                    AnchorPoint = new PointClass
                    {
                        X = point.X,
                        Y = point.Y,
                        Z = 0
                    },
                    Height = Height,
                    Depth = Depth,
                    Text = BaseText + index
                };
                elements.Add(element);
                index++;
                feature = featureCursor.NextFeature();
            }

            ComReleaser.ReleaseCOMObject(feature);
            ComReleaser.ReleaseCOMObject(featureCursor);
            ComReleaser.ReleaseCOMObject(featureClass);

            return elements;
        }

        public void Remove(string layerName)
        {
            if (_label3DSource.ContainsKey(layerName))
                _label3DSource[layerName].Clear();
        }
    }
}